#include "FaceDetection.h"
#include <QDebug>

const std::string FaceDetection::faceCascadeName = "Cascades/haarcascade_frontalface_alt.xml";

const cv::Size FaceDetection::defMinSize(100, 100);
const cv::Size FaceDetection::defMaxSize(200, 200);

//const cv::Size FaceDetection::defMinSize(100 * 2, 100 * 2);
//const cv::Size FaceDetection::defMaxSize(200 * 2, 200 * 2);
//const cv::Size FaceDetection::defMinEyeSize(5 * 2, 5 * 2);
//const cv::Size FaceDetection::defMaxEyeSize(50 * 2, 50 * 2);
//const cv::Size FaceDetection::defMinNoseSize(5 * 2, 5 * 2);
//const cv::Size FaceDetection::defMaxNoseSize(200 * 2, 200 * 2);
//const cv::Size FaceDetection::defMinMouthSize(10 * 2, 10 * 2);
//const cv::Size FaceDetection::defMaxMouthSize(100 * 2, 100 * 2);

FaceDetection::FaceDetection(void) : Filter(1, 1)
{
	bool r;
	r = faceCascade.load(faceCascadeName);

	minSize = defMinSize;
	maxSize = defMaxSize;
	ROI = cv::Rect(0, 0, 640, 480);

	outputs[0] = cv::Mat(1,4,CV_32SC1);
}

FaceDetection::~FaceDetection(void)
{
}

void FaceDetection::Process()
{
	std::vector<cv::Rect> faces;
	cv::Mat frameGray;
	if (inputs[0]->channels() == 3)
	{
		cv::cvtColor(*inputs[0], frameGray, CV_BGR2GRAY);
	}
	else if (inputs[0]->channels() == 1)
	{
		frameGray = inputs[0]->clone();
	}

	cv::equalizeHist(frameGray, frameGray);

	cv::Mat frameGrayROI = frameGray(ROI);
	faceCascade.detectMultiScale(frameGrayROI, faces, 1.2, 2, 0|CV_HAAR_SCALE_IMAGE, minSize, maxSize);

	if (!faces.size())
	{
		ROI = cv::Rect(cv::Point(0,0), cv::Size(inputs[0]->cols, inputs[0]->rows));
		faceCascade.detectMultiScale(frameGray, faces, 1.2, 2, 0|CV_HAAR_SCALE_IMAGE, minSize, maxSize);
	}

	if (faces.size() > 0)
	{
		cv::Rect face = cv::Rect(faces[0].x + ROI.x, faces[0].y + ROI.y, faces[0].width, faces[0].height);
		cv::Mat faceROI = (*inputs[0])(face);

		outputs[0].at<int>(0,0) = face.x;
		outputs[0].at<int>(0,1) = face.y;
		outputs[0].at<int>(0,2) = face.width;
		outputs[0].at<int>(0,3) = face.height;

		minSize = cv::Size(face.width * 0.85, face.height * 0.85);
		maxSize = cv::Size(face.width * 1.15, face.height * 1.15);

		ROI = cv::Rect(face.x - face.width * 0.75, face.y - face.height * 0.75, face.width * 2.5, face.height * 2.5);
		ROI.x = MAX(0, ROI.x);
		ROI.y = MAX(0, ROI.y);
		if (ROI.x + ROI.width >= inputs[0]->cols)
			ROI.width = inputs[0]->cols - ROI.x - 1;
		if (ROI.y + ROI.height >= inputs[0]->rows)
			ROI.height= inputs[0]->rows - ROI.y - 1;

		//qDebug() << "Face found ";
	} 
	else
	{
		minSize = defMinSize;
		maxSize = defMaxSize;
		ROI = cv::Rect(cv::Point(0,0), cv::Size(inputs[0]->cols, inputs[0]->rows));

		outputs[0] = cv::Scalar_<int>(0);
		outputValid[0] = false;

		//qDebug() << "No face found ";
	}

	
}
